<?php

abstract class x_session_base
{
	const sid_error_string = "SID was not generated but requested. You need to enable new sessions creation.";

	protected $session_store_path;

	protected $session_id;

	/**
	 * @var x_session_conf_base
	 */
	protected $conf;

	/**
	 * @var x_session_store
	 */
	protected $store;

	public function __construct($session_store_path)
	{
		$this->session_store_path = $session_store_path;
	}

	public function check_session_is_created($write_begin = false)
	{
		return;
	}

	public function session_write_begin()
	{
		if (is_null($this->session_id))
		{
			trigger_error(self::sid_error_string);
		}
		return $this->store->session_write_begin();
	}

	public function session_write_commit()
	{
		if (is_null($this->session_id))
		{
			trigger_error(self::sid_error_string);
		}
		return $this->store->session_write_commit();
	}

	public function session_write_rollback()
	{
		if (is_null($this->session_id))
		{
			trigger_error(self::sid_error_string);
		}
		return $this->store->session_write_rollback();
	}

	public function is_session_started()
	{
		return !is_null($this->session_id);
	}

	public function get_session_id()
	{
		if (is_null($this->session_id))
		{
			trigger_error(self::sid_error_string);
		}
		return $this->session_id;
	}

	public function get_session_name()
	{
		return $this->conf->get_session_name();
	}

	protected function try_auth_over_cookie($write_begin = false)
	{
		//ddn(2, "!");
		if (isset($_COOKIE[$this->conf->get_session_name()]))
		{

			$this->session_id = $_COOKIE[$this->conf->get_session_name()];
			// Correct session_id
			if (preg_match("/^[a-f0-9]{32}$/", $this->session_id))
			{
				//dd($this->session_id);
				$this->store = new x_session_store($this->session_store_path, $this->session_id, $this->conf->get_session_storage_deep_level());
				// Session exists
				if ($this->store->session_exists())
				{
					$this->store->session_load($write_begin);
					// IP is good
					if (isset($_SESSION["x_session"]["ip"]) and $_SESSION["x_session"]["ip"] == $_SERVER['REMOTE_ADDR'])
					{
						// Session is not expired
						if (!isset($_SESSION["x_session"]["expires_time"]) or $_SESSION["x_session"]["expires_time"] >= time())
						{
							return true;
						}
					}
					$this->store->session_delete();
				}
			}
		}
		$this->session_id = null;
		return false;
	}

	protected function create_new_session($session_cookie_path, $session_cookie_domain, $write_begin = false)
	{
		do
		{
			if ($this->store)
			{
				$this->store->__destruct();
			}
			$this->session_id = md5(rand() . time() . $_SERVER['REMOTE_ADDR']);
			$this->store = new x_session_store($this->session_store_path, $this->session_id, $this->conf->get_session_storage_deep_level());
		}
		while ($this->store->session_exists());

		$this->store->session_load(true);

		$created_time = time();
		$expires_time = $created_time + $this->conf->get_session_life_time();

		$this->set_auth_cookie($this->conf, $session_cookie_path, $session_cookie_domain, $expires_time);

		$_SESSION["x_session"] = array(
		"created_time" => $created_time,
		"expires_time" => $expires_time,
		"ip" => $_SERVER['REMOTE_ADDR'],
		);

		if (!$write_begin)
		{
			$this->store->session_write_commit();
		}
	}

	protected function set_auth_cookie(x_session_conf $conf, $session_cookie_path, $session_cookie_domain, $expires_time, $session_name = null, $session_id = null, $clean_cookie = false)
	{
		$path = $session_cookie_path ? $session_cookie_path : $conf->get_session_cookie_path();
		$domain = $session_cookie_domain ? $session_cookie_domain : $conf->get_session_cookie_domain();
		if ($domain !== false)
		{
			$domain = $_SERVER['HTTP_HOST'];
		}

		/* 5 - according to my experiments, if domain name length is 4 chars or less,
		 IE6 doesn't accept cookies (hm... it accepts cookies for '.b.b' - I can't understand
		 this, but let's leave this '5'). */

		$can_send_domain = strpos($domain, ".") && strlen($domain) > 5;

		if (is_null($session_name))
		{
			$session_name = $this->conf->get_session_name();
		}
		if (is_null($session_id))
		{
			$session_id = $this->session_id;
		}

		header("Set-Cookie: " . $session_name . "=" . $session_id
		. ($conf->get_session_clean_on_browser_close() && !$clean_cookie ? "" : "; Expires=" . date("r", $expires_time))
		. ($path ? "; path=" . $path : "")
		. ($domain && $can_send_domain ? "; domain=" . $domain : "") // $can_send_domain - otherwise session does not work on localhost and etc.
		. "; HttpOnly");
	}

}

?>